/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package casino;

import java.util.Set;

/**
 * Abstract class for players in the casino. Players have a starting stake, will
 * only be playing for a certain number of rounds and will be playing at the roulette
 * table.
 * 
 * @author amaghfur
 * @since 1.0
 */
public abstract class Player {
    
    /** money in possession */
    private Rational stake;
    /** rounds left to play */
    private int rounds;
    /** table to play */
    private Table table;

    public Player(Table tableToPlay) {
        table = tableToPlay;
    }
    
    /**
     * Setter for stake.
     * 
     * @param newStake 
     */
    public void setStake(Rational newStake) {
        if (newStake.lessThan(new Rational(0)))
            stake = new Rational(0);
        else
            stake = newStake;
    }
    
    /**
     * Getter for stake
     * 
     * @return  stake 
     */
    protected Rational getStake() {
        return stake;
    }
    
    /**
     * Setter for roundsToGo.
     * 
     * @param newRounds 
     */
    public void setRounds(int newRounds) {
        rounds = newRounds;
    }
    
    /**
     * Getter for table
     * 
     * @return  table 
     */
    protected Table getTable() {
        return table;
    }
    
    /** 
     * Asks the player if he is playing a round or not. He is only playing if he has enough stake
     * and rounds remaining. The number of rounds left to play gets decremented if playing that round.
     * 
     * @return  true if playing, otherwise false
     */
    public boolean playing() {
        if (stake.greaterThan(new Rational(0)) && rounds > 0) {
            rounds--;
            return true;
        }
        else
            return false;
    }
    
    /**
     * Tells this player to place bets.
     */
    abstract void placeBets();
    
    /**
     * Tells this player the specified bet has won.
     * 
     * @param bet   the bet that won
     */
    abstract void win(Bet bet);
    
    /**
     * Tells this player the specified bet has lost.
     * 
     * @param bet   the bet that lost
     */
    abstract void lose(Bet bet);
    
    /**
     * Notifies the player of each spin and the result. This will always be
     * invoked even if the player places no bets.
     * 
     * @param outcomes  set of winning outcomes 
     */
    abstract void winners(Set<Outcome> outcomes);
    
    /**
     * Reset this player's state.
     */
    abstract void reset();
        
}
